
/**
 *  \file hci_transport_internal.h
 *
 *  Internal Module Header File for HCI Transport module.
 */

/*
 *  Copyright (C) 2013. Mindtree Ltd.
 *  All rights reserved.
 */

#ifndef _H_HCI_TRANSPORT_INTERNAL_
#define _H_HCI_TRANSPORT_INTERNAL_

/* --------------------------------------------  Header File Inclusion */
#include "BT_common.h"
#include "BT_bottom_half.h"
#include "hci_transport.h"

#ifdef BT_BCSP
#include "bcsp.h"
#endif /* BT_BCSP */


/* --------------------------------------------  Type Definitions */

/* HCI Transport Debug Related */
#ifndef HT_NO_DEBUG
#define HT_ERR(...)     BT_debug_error(BT_MODULE_ID_HT, __VA_ARGS__)
#define HT_SPY_LOG(...) BT_debug_trace(BT_MODULE_ID_HT, __VA_ARGS__)
#else  /* HT_NO_DEBUG */
#define HT_ERR          BT_debug_null
#define HT_SPY_LOG      BT_debug_null
#endif /* HT_NO_DEBUG */

#ifdef HT_DEBUG

#define HT_TRC(...)     BT_debug_trace(BT_MODULE_ID_HT, __VA_ARGS__)
#define HT_INF(...)     BT_debug_info(BT_MODULE_ID_HT, __VA_ARGS__)

#else  /* HT_DEBUG */

#define HT_TRC          BT_debug_null
#define HT_INF          BT_debug_null

#endif /* HT_DEBUG */

#ifdef HT_INTR_DEBUG
#define HT_INTR_TRC(...)    BT_debug_trace(BT_MODULE_ID_HT, __VA_ARGS__)
#define HT_debug_dump_bytes(data, datalen) BT_debug_dump_bytes(BT_MODULE_ID_HT, (data), (datalen))
#else  /* HT_INTR_DEBUG */
#define HT_INTR_TRC         BT_debug_null
#define HT_debug_dump_bytes(data, datalen)
#endif /* HT_INTR_DEBUG */


/* HCI Transport Read Task State Values */
#define HT_WAITING                      0x01
#define HT_RUNNING                      0x02
#define HT_SHUTDOWN                     0x03

/* HCI Transport Packet Delivery States */
#define HT_PACKET_TYPE                  0x00
#define HT_PACKET_CMD_HEADER            0x01
#define HT_PACKET_EVENT_HEADER          0x02
#define HT_PACKET_ACL_HEADER            0x03
#define HT_PACKET_SCO_HEADER            0x04
#define HT_PACKET_ISO_HEADER            0x05
#define HT_PACKET_PAYLOAD               0x0F


/* --------------------------------------------  Structures */
#ifdef HT_ENABLE_SPY
typedef struct ht_spy
{
    /* Minimum Free Space */
    UINT32 min_free_space;

    /**
     * Maximum Filled Space.
     *
     * Note: It is possible to derive free space from filled space.
     * Maintaining it separately to also verify the consistencies
     * of these values.
     */
    UINT32 max_filled_space;

    /**
     * Maximum and minimum received HCI Event and L2CAP data packet
     * sizes are captured in the HCI Layer.
     */

} HT_SPY;
#endif /* HT_ENABLE_SPY */


/* --------------------------------------------  Macros */
/* HCI Transport Mutex Lock & Unlock */
#ifndef BT_DISABLE_MUTEX
#define ht_lock()       BT_thread_mutex_lock(&ht_mutex)
#define ht_unlock()     BT_thread_mutex_unlock(&ht_mutex)
#else
#define ht_lock()
#define ht_unlock()
#endif /* BT_DISABLE_MUTEX */

/* To Get/Set HCI Transport Circular Buffer Read & Write Pointers */
#define HT_BUFFER_GET_RD_PTR(rd)        (rd) = ht_buffer_rd_ptr;
#define HT_BUFFER_SET_RD_PTR(rd)        ht_buffer_rd_ptr = (rd);
#define HT_BUFFER_GET_WR_PTR(wr)        (wr) = ht_buffer_wr_ptr;
#define HT_BUFFER_SET_WR_PTR(wr)        ht_buffer_wr_ptr = (wr);

/* To Get Free Space in HCI Transport Circular Buffer */
#define HT_BUFFER_GET_SPACE(rd, wr, cnt) \
        (cnt) = ((rd) - ((wr) + 1)) & (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1);

/*
 *  To Get Free (Linear) Space in HCI Transport Circular Buffer
 *  (so that 'BT_mem_copy' could be called to copy incoming data)
 */
#define HT_BUFFER_GET_SPACE_LINEAR(rd, wr, cnt) \
        { \
            UINT16 cnt_end; \
            cnt_end = (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1 - (wr)); \
            (cnt) = (cnt_end + (rd)) & (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1); \
            if ((cnt) > cnt_end) (cnt) = cnt_end + 1; \
        }

/* To Get Amount of Data queued in HCI Transport Circular Buffer */
#define HT_BUFFER_GET_COUNT(rd, wr, cnt) \
        (cnt) = ((wr) - (rd)) & (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1);

/*
 *  To Get Amount of Data (Linear) queued in HCI Transport Circular Buffer
 *  (so that 'BT_mem_copy' could be called to copy incoming data)
 */
#define HT_BUFFER_GET_COUNT_LINEAR(rd, wr, cnt) \
        { \
            UINT16 cnt_end; \
            cnt_end = (HCI_TRANSPORT_MAX_BUFFER_SIZE - (rd)); \
            (cnt) = ((wr) + cnt_end) & (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1); \
            if ((cnt) >= cnt_end) (cnt) = cnt_end; \
        }

/* To Update/Increment HCI Transport Circular Buffer Read & Write Pointers */
#define HT_BUFFER_UPDATE_RDWR_PTR(ptr, cnt) \
        (ptr) = ((ptr) + (cnt)) & (HCI_TRANSPORT_MAX_BUFFER_SIZE - 1);

#ifdef HT_ENABLE_SPY
#define HT_SPY_UPDATE_MIN_FREE_SPACE(cur_val, new_val) \
        (cur_val) = BT_GET_MIN((cur_val), (new_val))

#define HT_SPY_UPDATE_MAX_FILLED_SPACE(cur_val, new_val) \
        (cur_val) = BT_GET_MAX((cur_val), (new_val))
#else
#define HT_SPY_UPDATE_MIN_FREE_SPACE(cur_val, new_val)
#define HT_SPY_UPDATE_MAX_FILLED_SPACE(cur_val, new_val)
#endif /* HT_ENABLE_SPY */

/* --------------------------------------------  Function Declarations */
void hci_transport_deliver_data (void);
UCHAR hci_transport_wait_for_data (void);
void hci_transport_handle_hci_data (void);


/* --------------------------------------------  Task Model Specific Changes */

#ifdef BT_TRANSPORT_SINGLE_TASK

#define hci_transport_task_init()
#define hci_transport_task_bt_shutdwon()

#else  /* BT_TRANSPORT_SINGLE_TASK */

void hci_transport_task_init (void);
void hci_transport_task_bt_shutdwon (void);

#ifndef BT_DISABLE_MUTEX
#ifndef HAVE_CONDWAIT_WO_MUTEX
#define ht_wait()       BT_thread_cond_wait(&ht_cond, &ht_mutex)
#else /* HAVE_CONDWAIT_WO_MUTEX */
#define ht_wait()       \
                        ht_unlock(); \
                        BT_thread_cond_wait(&ht_cond, &ht_mutex); \
                        ht_lock()
#endif /* HAVE_CONDWAIT_WO_MUTEX */

#define ht_signal()     BT_thread_cond_signal(&ht_cond)
#else
#define ht_wait()
#define ht_signal()
#endif /* BT_DISABLE_MUTEX */

BT_THREAD_RETURN_TYPE ht_read_task_start_routine (BT_THREAD_ARGS args);

#endif /* BT_TRANSPORT_SINGLE_TASK */

#ifdef HT_ENABLE_SPY
void ht_spy_init(void);
void ht_spy_bt_init(void);
void ht_spy_log(void);
#else
#define ht_spy_init()
#define ht_spy_bt_init()
#define ht_spy_log()
#endif /* HT_ENABLE_SPY */

/* --------------------------------------------  Platform Specific Changes */
void ht_read_task_create_pl ( void );
UCHAR ht_read_task_shutdown_pl ( void );

#if (defined WINDOWS_SDK)

UCHAR ht_read_task_signal_pending_pl(void);

#else

#define ht_read_task_signal_pending_pl()        0

#endif /* WINDOWS_SDK */

#endif /* _H_HCI_TRANSPORT_INTERNAL_ */

